package com.bookmanagement.controller;

import com.bookmanagement.entity.Borrowing;
import com.bookmanagement.service.BookService;
import com.bookmanagement.service.BorrowingService;
import com.bookmanagement.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 借阅控制器，处理借阅相关请求
 * 注解@Controller标识该类为Spring MVC控制器，负责接收和处理HTTP请求
 * @RequestMapping("/borrowing")指定该控制器的基础请求路径，所有方法的路径都以此为前缀
 */
@Controller
@RequestMapping("/borrowing")
public class BorrowingController {

    // 自动注入BorrowingService实例，用于处理借阅相关的业务逻辑
    @Autowired
    private BorrowingService borrowingService;
    // 自动注入BookService实例，用于处理图书相关的业务逻辑（如查询图书信息）
    @Autowired
    private BookService bookService;
    // 自动注入UserService实例，用于处理用户相关的业务逻辑（如验证用户身份）
    @Autowired
    private UserService userService;

    /**
     * 跳转到借阅页面（学生功能）
     * @GetMapping("/student/borrow/{bookId}")表示接收GET请求，路径为/borrowing/student/borrow/图书ID
     * @PathVariable Long bookId用于获取URL路径中的图书ID参数（如/borrow/100中的100）
     * Model model是Spring MVC的模型对象，用于向前端页面传递数据
     */
    @GetMapping("/student/borrow/{bookId}")
    public String borrowPage(@PathVariable Long bookId, Model model) {
        // 调用bookService的findById方法，根据图书ID查询图书详情
        // 将查询到的图书对象存入model，前端页面可通过${book}获取图书信息（如书名、作者）
        model.addAttribute("book", bookService.findById(bookId));
        // 返回视图名"student/borrow"，Spring MVC会定位到templates/student/borrow.html页面
        return "student/borrow";
    }

    /**
     * 提交借阅请求（学生功能）
     * @PostMapping("/student/create")表示接收POST请求，路径为/borrowing/student/create
     * @ResponseBody注解表示返回结果会直接转换为JSON格式（而非跳转页面）
     * @RequestBody Borrowing borrowing用于接收前端传递的JSON格式借阅数据（如应还时间、图书ID）
     * HttpServletRequest request用于获取请求相关信息（如请求头中的令牌）
     * Long userId是借阅人的用户ID（从前端传递或从令牌中解析）
     */
    @PostMapping("/student/create")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> createBorrowing(@RequestBody Borrowing borrowing,
                                                               HttpServletRequest request, Long userId) {
        // 创建响应结果Map，用于封装返回给前端的数据（状态码、消息、数据）
        Map<String, Object> response = new HashMap<>();
        try {
            // 设置借阅时间为当前系统时间（确保时间准确性，避免前端传递的时间有误）
            borrowing.setBorrowTime(LocalDateTime.now());
            // 调用borrowingService的createBorrowing方法，处理借阅业务逻辑（如验证库存、创建借阅记录）
            borrowingService.createBorrowing(borrowing, userId);
            // 借阅成功时，设置响应状态码为0（成功标识），消息为成功提示
            response.put("code", 0);
            response.put("message", "借阅请求提交成功");
            response.put("data", null); // 无额外数据返回时设为null
            // 使用ResponseEntity.ok()返回200状态码和响应数据
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            // 若业务逻辑中抛出异常（如图书已借出、用户无权限），捕获异常并返回错误信息
            response.put("code", 1); // 状态码1表示失败
            response.put("message", e.getMessage()); // 错误消息（如"图书库存不足"）
            // 使用ResponseEntity.badRequest()返回400状态码和错误数据
            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 查看个人借阅记录（学生功能）
     * @GetMapping("/student/borrowings")表示接收GET请求，路径为/borrowing/student/borrowings
     * Model model用于向前端页面传递借阅记录数据
     * HttpServletRequest request用于获取请求信息
     * Long userId是当前登录学生的用户ID
     */
    @GetMapping("/student/borrowings")
    public String getBorrowings(Model model, HttpServletRequest request, Long userId) {
        // 调用borrowingService的getBorrowingsByUser方法，查询该用户的所有借阅记录
        List<Borrowing> borrowings = borrowingService.getBorrowingsByUser(userId);
        // 将借阅记录列表存入model，前端页面可通过${borrowings}遍历展示（如借阅时间、图书名）
        model.addAttribute("borrowings", borrowings);
        // 返回视图名"student/borrowings"，跳转到个人借阅记录页面
        return "student/borrowings";
    }

    /**
     * 管理员借阅管理页面
     */
    @GetMapping("/admin/borrowings")
    public String getAdminBorrowings(@RequestParam(defaultValue = "1") int pageNum,
                                     @RequestParam(defaultValue = "10") int pageSize,
                                     @RequestParam(required = false) String date,
                                     @RequestParam(required = false) String bookTitle,
                                     @RequestParam(required = false) String username,
                                     Model model, HttpServletRequest request) {

        LocalDateTime borrowDate = date != null && !date.isEmpty() ?
                LocalDateTime.parse(date.replace("T", " ")) : null;
        Map<String, Object> result = borrowingService.getAllBorrowings(pageNum, pageSize, borrowDate, bookTitle, username);
        model.addAttribute("borrowings", result.get("items"));
        model.addAttribute("total", result.get("total"));
        model.addAttribute("pageNum", pageNum);
        model.addAttribute("pageSize", pageSize);
        model.addAttribute("date", date);
        model.addAttribute("bookTitle", bookTitle);
        return "admin/borrowings";
    }

    /**
     * 管理员确认归还
     */
    @PostMapping("/admin/return/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> returnBorrowingAdmin(@PathVariable Long id,
                                                                    HttpServletRequest request) {
        Map<String, Object> response = new HashMap<>();

        try {
            borrowingService.returnBorrowing(id);
            response.put("code", 0);
            response.put("message", "确认归还成功");
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            response.put("code", 1);
            response.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 管理员删除借阅记录
     */
    @PostMapping("/admin/delete/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> deleteBorrowingAdmin(@PathVariable Long id,
                                                                    HttpServletRequest request) {
        Map<String, Object> response = new HashMap<>();
        try {
            borrowingService.deleteBorrowing(id);
            response.put("code", 0);
            response.put("message", "删除借阅记录成功");
            return ResponseEntity.ok(response);
        } catch (RuntimeException e) {
            response.put("code", 1);
            response.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }




    /**
     * 学生续期借阅
     * 注意：从代码路径"/student/renew/{id}"来看，当前接口被设计为学生端访问路径，
     * 但根据业务逻辑，续期功能实际应属于管理员端操作（可能存在路径设计与实际业务的不匹配）
     */
    @PostMapping("/student/renew/{id}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> renewBorrowing(
            @PathVariable Long id,  // 路径参数，代表要续期的借阅记录ID
            @RequestBody Map<String, Integer> body,  // 接收前端传递的JSON数据，包含续期天数
            HttpServletRequest request) {  // 请求对象，可用于获取令牌等信息

        // 从请求体中获取续期天数（前端通过"renewalDays"字段传递）
        Integer renewalDays = body.get("renewalDays");

        // 创建响应结果Map，用于封装返回给前端的状态信息
        Map<String, Object> response = new HashMap<>();

        try {
            // 调用业务层方法执行续期逻辑：
            // 参数说明：id（借阅记录ID）、null（用户ID，此处未使用，可能存在参数设计冗余）、renewalDays（续期天数）
            borrowingService.renewBorrowing(id, null, renewalDays);

            // 续期成功时的响应数据：状态码0表示成功，返回成功提示
            response.put("code", 0);
            response.put("message", "续期成功");
            return ResponseEntity.ok(response);  // 返回200状态码及成功响应

        } catch (RuntimeException e) {
            // 续期失败时的响应数据（如超过最大续期次数、图书已逾期等）：
            // 状态码1表示失败，返回具体错误信息（来自业务层抛出的异常消息）
            response.put("code", 1);
            response.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(response);  // 返回400状态码及错误响应
        }
    }
}
